//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Query Application Block
//===============================================================================

using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using EntLibContrib.Query.Configuration.Design;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ContainerModel;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Design;

namespace EntLibContrib.Query.Configuration
{
	/// <summary>
	/// Configuration data defining <see cref="ParameterSetData"/>. This configuration section defines the name and type
	/// of the <see cref="IParameterSet"/> class
	/// </summary>
    [ResourceDescription(typeof(DesignResources), "ParameterSetDataDescription")]
    [ResourceDisplayName(typeof(DesignResources), "ParameterSetDataDisplayName")]
    [ViewModel(QueryDesignTime.ViewModelTypeNames.ParameterSetDataViewModel)]
    public class ParameterSetData : NamedConfigurationElement
	{
		private const string parametersProperty = "parameters";

        /// <summary>
        /// Initializes a new instance of the <see cref="ParameterSetData"/> class.
        /// </summary>
        public ParameterSetData()
        {
        }

        /// <summary>
        /// Initialize a new instance of the <see cref="ParameterSetData"/> class with a name and the type of <see cref="IParameterSet"/>.
        /// </summary>
        /// <param name="name">The name of the configured <see cref="IParameterSet"/>.</param>
        public ParameterSetData(string name)
            : base(name)
        {
        }

		/// <summary>
		/// Gets or sets the list of parameters associated with
		/// the query.
		/// </summary>
		/// <value>A collection of <see cref="ParameterData"/>.</value>
		[ConfigurationProperty(parametersProperty, IsRequired = false)]
        [ConfigurationCollection(typeof(ParameterData))]
        [ResourceDescription(typeof(DesignResources), "ParametersDescription")]
        [ResourceDisplayName(typeof(DesignResources), "ParametersDisplayName")]
        [PromoteCommands]
        public NameTypeConfigurationElementCollection<ParameterData, CustomParameterData> Parameters
		{
			get { return (NameTypeConfigurationElementCollection<ParameterData, CustomParameterData>)base[parametersProperty]; }
		}
		
		/// <summary>
		/// Get the set of <see cref="TypeRegistration"/> objects needed to
		/// register the Policy Injection settings represented by this config section.
		/// </summary>
		/// <returns>The set of <see cref="TypeRegistration"/> objects.</returns>
		public IEnumerable<TypeRegistration> GetRegistrations()
		{ 
            var registrations = new List<TypeRegistration>();

            registrations.AddRange(Parameters.SelectMany(x => x.GetRegistrations(BuildName(x.Name))));
            
            var parameterSetRegistration = new TypeRegistration<IParameterSet>(() =>
                new ParameterSet(
                    Container.ResolvedEnumerable<IParameter>(Parameters.Select(x => BuildName(x.Name)))))
			{
				Lifetime = TypeRegistrationLifetime.Transient,
				Name = Name,
                IsPublicName = true
			};
            
            registrations.Add(parameterSetRegistration);

			return registrations;
		}

        /// <summary>
        /// Builds a name with the supplied prefix. 
        /// </summary>
        /// <param name="suffix">Suffix to use when building a name</param>
        /// <returns>A name as string</returns>
        protected string BuildName(string suffix)
        {
            return Name + "." + suffix;
        }
	}
}